package com.letv.whatslive.web.util;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.letv.whatslive.model.mysql.system.SysFunction;
import com.letv.whatslive.model.mysql.system.SysUser;
import com.letv.whatslive.web.constant.WebConstants;
import com.letv.whatslive.web.service.system.SysFunctionService;
import com.letv.whatslive.web.service.system.SysUserService;
import com.letv.whatslive.web.util.util.SpringUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Title: 处理web相关功能的工具类
 * Desc: 处理web相关功能的工具类
 * User: crespo
 * Company: www.gitv.cn
 * Date: 13-11-21 下午5:36
 */
@Component
public class WebUtils {

    private static final Logger logger = LoggerFactory.getLogger(WebUtils.class);

    private static SysFunctionService sysFunctionService;
    private static SysUserService sysUserService;

    private static WebUtils webUtils;

    static{
        if (sysFunctionService == null) {
            sysFunctionService = SpringUtils.getBean(SysFunctionService.class, "sysFunctionService");
        }
        if (sysUserService == null) {
            sysUserService = SpringUtils.getBean(SysUserService.class, "sysUserService");
        }
        if(webUtils==null){
            webUtils=SpringUtils.getBean(WebUtils.class, "webUtils");
        }
    }

    /**
     * 重定向至登录页面
     * @param request
     * @param response
     * @throws Exception
     */
    public static void redirect2LoginPage(HttpServletRequest request, HttpServletResponse response) throws Exception{
        response.sendRedirect(request.getContextPath() + WebConstants.LOGIN_PAGE_URI);
    }

    /**
     * 获取登录用户对象
     * @param request
     * @return
     */
    public static SysUser getLoginUser(HttpServletRequest request) {
        HttpSession session = request.getSession();
        if(session != null){
            Object userObj = session.getAttribute(WebConstants.WHATSLIVE_SESSION_USERINFO_KEY);
            if(userObj != null){
                return (SysUser) userObj;
            }
        }
        return null;
    }

    /**
     * 获取登录用户对象id
     *
     * @param request
     * @return
     */
    public static Integer getLoginUserId(HttpServletRequest request) {
        HttpSession session = request.getSession();
        if (session != null) {
            Object userObj = session.getAttribute(WebConstants.WHATSLIVE_SESSION_USERINFO_KEY);
            if (userObj != null) {
                return ((SysUser) userObj).getId();
            }
        }
        return -1;
    }

    /**
     * 获取登录用户的中文用户名，为null时返回空字符串
     * @param request
     * @return
     */
    public static String getLoginUserNameNotNull(HttpServletRequest request){
        SysUser sysUser = getLoginUser(request);
        if(sysUser != null && StringUtils.isNotEmpty(sysUser.getUserName())){
            return sysUser.getUserName();
        }
        return StringUtils.EMPTY;
    }

    /**
     * 获取登录用户的APPID，为null时返回空字符串
     * @param request
     * @return
     */
    public static String getLoginUserAPPIDNotNull(HttpServletRequest request){
        SysUser sysUser = getLoginUser(request);
        if(sysUser != null && StringUtils.isNotEmpty(sysUser.getAppId())){
            return sysUser.getAppId();
        }
        return StringUtils.EMPTY;
    }

    /**
     * 获取拥有权限的顶级功能（子系统）
     * @param request
     * @return
     */
    public static List<SysFunction> getTopFunctionListByLoginUser(HttpServletRequest request){
        return getFunctionListByLoginUserAndParentFuncId(request, 0);
    }

    public static List<SysFunction> getTopFunctionListByLoginUser_doCache(HttpServletRequest request){
        return getFunctionListByLoginUserAndParentFuncId_Cache(request, 0);
    }

    public List<SysFunction> getTopFunctionListByLoginUserNotStatic(HttpServletRequest request){
        return getTopFunctionListByLoginUser(request);
    }

    public static List<SysFunction> getTopFunctionListByLoginUser_Cache(HttpServletRequest request){
        return webUtils.getTopFunctionListByLoginUserNotStatic(request);
    }

    /**
     * 获取拥有权限的顶级功能（子系统）
     * @param request
     * @return
     */
    public static List<SysFunction> getFunctionListByLoginUserAndParentFuncId(HttpServletRequest request, Integer parentFuncId){
        SysUser sysUser = getLoginUser(request);
        if(sysUser == null){
            logger.error("未登录，非法操作");
            return Lists.newArrayList();
        }
        List<SysFunction> fList = sysFunctionService.getFunctionListByParentId(parentFuncId);
        List<SysFunction> funcList = Lists.newArrayList();
        if(fList != null){
            for(SysFunction f : fList){
                if(sysUserService.hasFuncRight(sysUser.getId(), f.getId())){
                    funcList.add(f);
                }
            }
        }
        return funcList;
    }

    private static boolean hasFuncRight(HttpSession session,Integer userId,Integer funcId){
        Map<Integer,SysFunction> sysFunctionMap=getSysFunctionMap(session);
        List<Boolean> hasFuncRightList=null;
        boolean retVal=false;
        if(session.getAttribute("hasFuncRight_cache" + userId)!=null){
            Map<Integer,Boolean> sysFunctionIdMap=(Map<Integer,Boolean>)session.getAttribute("hasFuncRight_cache"+userId);
            return sysFunctionIdMap.get(funcId);
        }
        else{
            Set<Integer> sysFunctionList=(Set<Integer>)sysFunctionMap.keySet();
            Map<Integer,Boolean> sysFunctionIdMap=Maps.newHashMap();
            for(Integer sysFunctionId:sysFunctionList){
                boolean value=sysUserService.hasFuncRight(userId, sysFunctionId);
                sysFunctionIdMap.put(sysFunctionId, value);
                if(sysFunctionId.equals(funcId))
                    retVal=value;
            }
            session.setAttribute("hasFuncRight_cache"+userId,sysFunctionIdMap);
        }
        return retVal;
    }

    public List<SysFunction> getFunctionListByLoginUserAndParentFuncIdNotStatic(HttpServletRequest request, Integer parentFuncId) {
        return getFunctionListByLoginUserAndParentFuncId(request, parentFuncId);
    }

    public static List<SysFunction> getFunctionListByLoginUserAndParentFuncId_doCache(HttpServletRequest request, Integer parentFuncId){
        SysUser sysUser = getLoginUser(request);
        if(sysUser == null){
            logger.error("未登录，非法操作");
            return Lists.newArrayList();
        }
        HttpSession session = request.getSession();
        Map<Integer,SysFunction> sysFunctionMap=getSysFunctionMap(session);
        List<SysFunction> fList=Lists.newArrayList();
        if(session.getAttribute("topFuncListHeaderPage_cache" + parentFuncId)!=null){
            List<Integer> sysFunctionIdList=(List<Integer>)session.getAttribute("topFuncListHeaderPage_cache"+parentFuncId);
            for(Integer sysFunctionId:sysFunctionIdList){
                fList.add(sysFunctionMap.get(sysFunctionId));
            }
        }
        else{
            Set<Integer> sysFunctionList=(Set<Integer>)sysFunctionMap.keySet();
            for(Integer sysFunctionId:sysFunctionList){
                List<SysFunction> FunctionListByParentFuncId=sysFunctionService.getFunctionListByParentId(sysFunctionId);
                if(FunctionListByParentFuncId!=null){
                    List<Integer> sysFunctionIdList=Lists.newArrayList();
                    for(SysFunction sysFunction:FunctionListByParentFuncId){
                        sysFunctionIdList.add(sysFunction.getId());
                    }
                    session.setAttribute("topFuncListHeaderPage_cache"+sysFunctionId,sysFunctionIdList);
                    if(sysFunctionId.equals(parentFuncId)){
                        fList=FunctionListByParentFuncId;
                    }
                }
            }
            List<SysFunction> FunctionListByParentFuncId=sysFunctionService.getFunctionListByParentId(0);
            if(FunctionListByParentFuncId!=null){
                List<Integer> sysFunctionIdList=Lists.newArrayList();
                for(SysFunction sysFunction:FunctionListByParentFuncId){
                    sysFunctionIdList.add(sysFunction.getId());
                }
                session.setAttribute("topFuncListHeaderPage_cache"+0,sysFunctionIdList);
            }
        }
        List<SysFunction> funcList = Lists.newArrayList();
        if(fList != null){
            for(SysFunction f : fList){
//                if(sysUserService.hasFuncRight(sysUser.getId(), f.getId())){
                if(hasFuncRight(session, sysUser.getId(), f.getId())) {
                    //对于可视化审核页面，如果有被举报的直播或者录播视频，需要提示红点
//                    if(WebConstants.noticeFunctionName.equals(f.getFuncName())){
//                        if(videoService.countReportProgramByPTypes(ProgramConstants.pType_live+","+ProgramConstants.pType_end)>0){
//                            f.setFuncName(f.getFuncName()+WebConstants.noticeImgHTML);
//                        }
//
//                    }
                    funcList.add(f);
                }
            }
        }
        return funcList;
    }

    public static List<SysFunction> getFunctionListByLoginUserAndParentFuncId_Cache(HttpServletRequest request, Integer parentFuncId){
        return webUtils.getFunctionListByLoginUserAndParentFuncIdNotStatic(request, parentFuncId);
    }

    public static String addQueryParam(String queryUrl, String key, String value){
        if(queryUrl == null){
            logger.error("queryUrl为空");
            return null;
        }
        if(queryUrl.indexOf("?") >= 0){
            return queryUrl + "&" + key + "=" + value;
        }else{
            return queryUrl + "?" + key + "=" + value;
        }
    }

    public static boolean isFuncActive(SysFunction func, int activeFId){
        if(func == null || activeFId <= 0){
            logger.error("参数错误，有参数为空");
            return false;
        }
        if(activeFId != 0){
            if(func.getIsLeaf() != null && func.getIsLeaf() == 1){
                //如果叶子节点，直接判断id是否相同
                return func.getId() == activeFId;
            }else{
                //非叶子节点，递归activeFId的所有父节点，查看是否在父节点中
                List<SysFunction> parentFuncList = getParentFunctionListByFuncId(activeFId);
                for(SysFunction f : parentFuncList){
                    if(f.getId().equals(func.getId())){
                        return true;
                    }
                }
            }

        }
        return false;
    }

    public static boolean isFuncActive_doCache(HttpServletRequest request,SysFunction func, int activeFId){
        if(func == null || activeFId <= 0){
            logger.error("参数错误，有参数为空");
            return false;
        }
        if(activeFId != 0){
            if(func.getIsLeaf() != null && func.getIsLeaf() == 1){
                //如果叶子节点，直接判断id是否相同
                return func.getId() == activeFId;
            }else{
                //非叶子节点，递归activeFId的所有父节点，查看是否在父节点中
                List<SysFunction> parentFuncList = getParentFunctionListByFuncId_Cache(request, activeFId);
                for(SysFunction f : parentFuncList){
                    if(f.getId().equals(func.getId())){
                        return true;
                    }
                }
            }

        }
        return false;
    }

    public boolean isFuncActiveNotStatic(HttpServletRequest request,SysFunction func, int activeFId) {
        return isFuncActive(func, activeFId);
    }

    public static boolean isFuncActive_Cache(HttpServletRequest request,SysFunction func, int activeFId) {
        return webUtils.isFuncActiveNotStatic(request, func, activeFId);
    }

    public static List<SysFunction> getParentFunctionListByFuncId(Integer funcId){
        return sysFunctionService.getParentFunctionListByFuncId(funcId);
    }

    public static List<SysFunction> getParentFunctionListByFuncId_Cache(HttpServletRequest request,Integer funcId){
        HttpSession session=request.getSession();
        Map<Integer,SysFunction> sysFunctionMap=getSysFunctionMap(session);
        List<SysFunction> retVals=Lists.newArrayList();
        List<Integer> retValIds=Lists.newArrayList();
        if(session.getAttribute("ParentFunctionListByFuncId" + funcId)!=null){
            retValIds=(List<Integer>)session.getAttribute("ParentFunctionListByFuncId"+funcId);
            for(Integer id:retValIds){
                retVals.add(sysFunctionMap.get(id));
            }
            return retVals;
        }
        else{
            Set<Integer> sysFunctionList=(Set<Integer>)sysFunctionMap.keySet();
            for(Integer sysFunctionId:sysFunctionList){
                List<SysFunction> sysFunctions=sysFunctionService.getParentFunctionListByFuncId(sysFunctionId);
                List<Integer> sysFunctionIds=Lists.newArrayList();
                for(SysFunction sysFunction:sysFunctions)
                    sysFunctionIds.add(sysFunction.getId());
                if(sysFunctionIds!=null){
                    session.setAttribute("ParentFunctionListByFuncId"+sysFunctionId,sysFunctionIds);
                    if(sysFunctionId.equals(funcId))
                        retVals=sysFunctions;
                }
            }
//            SysFunction topFunctionBySubFuncId=getTopFunctionBySubFuncId(0);
//            session.setAttribute("TopFunctionBySubFuncId"+0,topFunctionBySubFuncId.getId());
        }

        return retVals;
    }

    public static SysFunction getTopFunctionBySubFuncId(Integer subFuncId){
        SysFunction subFunc = sysFunctionService.getFuncById(subFuncId);
        if(subFunc.getParentFuncId() != null && subFunc.getParentFuncId() == 0){
            return subFunc;
        }else{
            List<SysFunction> parentFuncList = getParentFunctionListByFuncId(subFuncId);
            for(SysFunction f : parentFuncList){
                if(f.getParentFuncId() != null && f.getParentFuncId() == 0){
                    return f;
                }
            }
        }
        return null;
    }

    private static Map<Integer,SysFunction> getSysFunctionMap(HttpSession session){
        Map<Integer,SysFunction> sysFunctionMap=null;
        if(session.getAttribute("SysFunctionMap")==null) {
            sysFunctionMap= Maps.newHashMap();
            List<SysFunction> sysFunctionList=sysFunctionService.getfunctionList(null);
            for(SysFunction sysFunction:sysFunctionList)
                sysFunctionMap.put(sysFunction.getId(),sysFunction);
            session.setAttribute("SysFunctionMap",sysFunctionMap);
        }
        else{
            sysFunctionMap=(Map<Integer,SysFunction>)session.getAttribute("SysFunctionMap");
        }
        return sysFunctionMap;
    }

    private static Map<Integer,SysFunction> getSysFunctionMap_NoCache(){
        Map<Integer,SysFunction> sysFunctionMap=null;
        sysFunctionMap= Maps.newHashMap();
        List<SysFunction> sysFunctionList=sysFunctionService.getfunctionList(null);
        for(SysFunction sysFunction:sysFunctionList)
            sysFunctionMap.put(sysFunction.getId(),sysFunction);
        return sysFunctionMap;
    }

    public static SysFunction getTopFunctionBySubFuncId_doCache(HttpServletRequest request,Integer subFuncId){
        SysFunction retVal=null;
        HttpSession session=request.getSession();
        Map<Integer,SysFunction> sysFunctionMap=getSysFunctionMap(session);
        if(session.getAttribute("TopFunctionBySubFuncId"+subFuncId)!=null){
            return sysFunctionMap.get((Integer)session.getAttribute("TopFunctionBySubFuncId"+subFuncId));
        }
        else{
            Set<Integer> sysFunctionList=(Set<Integer>)sysFunctionMap.keySet();
            for(Integer sysFunctionId:sysFunctionList){
//                SysFunction topFunctionBySubFuncId=getTopFunctionBySubFuncId_Cache(request,sysFunctionId);
                SysFunction topFunctionBySubFuncId=getTopFunctionBySubFuncId(sysFunctionId);
                if(topFunctionBySubFuncId!=null){
                    session.setAttribute("TopFunctionBySubFuncId"+sysFunctionId,topFunctionBySubFuncId.getId());
                    if(sysFunctionId.equals(subFuncId))
                        retVal=topFunctionBySubFuncId;
                }
            }
//            SysFunction topFunctionBySubFuncId=getTopFunctionBySubFuncId(0);
//            session.setAttribute("TopFunctionBySubFuncId"+0,topFunctionBySubFuncId.getId());
        }
        return retVal;
    }

    public SysFunction getTopFunctionBySubFuncIdNotStatic(HttpServletRequest request,Integer subFuncId) {
        return getTopFunctionBySubFuncId(subFuncId);
    }

    public static SysFunction getTopFunctionBySubFuncId_Cache(HttpServletRequest request,Integer subFuncId) {
        return webUtils.getTopFunctionBySubFuncIdNotStatic(request, subFuncId);
    }

    public static SysFunction getFirstLeafFunctionByLoginUserAndTopFunction(HttpServletRequest request, Integer topFuncId){
        List<SysFunction> f1List = getFunctionListByLoginUserAndParentFuncId(request, topFuncId);
        if(f1List != null && f1List.size() > 0){
            SysFunction firstF1 = f1List.get(0);
            if(firstF1.getIsLeaf() != null && firstF1.getIsLeaf() == 1){
                return firstF1;
            }else{
                List<SysFunction> firstF2List = WebUtils.getFunctionListByLoginUserAndParentFuncId(request, firstF1.getId());
                for(SysFunction f2 : firstF2List){
                    if(f2.getIsLeaf() != null && f2.getIsLeaf() == 1){
                        return f2;
                    }
                }
            }
        }
        return null;
    }

    public static SysFunction getFirstLeafFunctionByLoginUserAndTopFunction_doCache(HttpServletRequest request, Integer topFuncId){
        List<SysFunction> f1List = getFunctionListByLoginUserAndParentFuncId_Cache(request, topFuncId);
        if(f1List != null && f1List.size() > 0){
            SysFunction firstF1 = f1List.get(0);
            if(firstF1.getIsLeaf() != null && firstF1.getIsLeaf() == 1){
                return firstF1;
            }else{
                List<SysFunction> firstF2List = WebUtils.getFunctionListByLoginUserAndParentFuncId_Cache(request, firstF1.getId());
                for(SysFunction f2 : firstF2List){
                    if(f2.getIsLeaf() != null && f2.getIsLeaf() == 1){
                        return f2;
                    }
                }
            }
        }
        return null;
    }

    public SysFunction getFirstLeafFunctionByLoginUserAndTopFunctionNotStatic(HttpServletRequest request, Integer topFuncId) {
        return getFirstLeafFunctionByLoginUserAndTopFunction(request, topFuncId);
    }

    public static SysFunction getFirstLeafFunctionByLoginUserAndTopFunction_Cache(HttpServletRequest request, Integer topFuncId) {
        return webUtils.getFirstLeafFunctionByLoginUserAndTopFunctionNotStatic(request,topFuncId);
    }

        /**
         * 根据用户名模糊查询相应用户
         * @param searchName
         * @param start
         * @param limit
         * @return
         */
    public static List<SysUser> getSysUserList(String searchName, Integer start, Integer limit) {
        return sysUserService.getSysUserList(searchName,start,limit);
    }

    /**
     * 根据用户名模糊查询相应用户名列表
     * @param searchName
     * @param start
     * @param limit
     * @return
     */
    public static List<String> getSysUserNameList(String searchName, Integer start, Integer limit) {
        List<String> userNames=Lists.newArrayList();
        List<SysUser> sysUserList= getSysUserList(searchName,start,limit);
        if(!(sysUserList==null||sysUserList.isEmpty())){
            for(SysUser sysUser:sysUserList){
                if(StringUtils.isNotBlank(sysUser.getLoginName()))
                    userNames.add(sysUser.getLoginName());
            }
        }
        return userNames;
    }

    public static Integer countSysUser(String searchName){
        return sysUserService.countSysUser(searchName);
    }

}
